package com.ehotting.edsta.circuitDesign.gen.arguments;

import com.ehotting.edsta.circuitDesign.enums.SceneTypeEnum;
import com.ehotting.edsta.circuitDesign.enums.StateTypeEnum;
import com.ehotting.edsta.circuitDesign.bean.request.RequestCodeExecute;
import com.ehotting.edsta.circuitDesign.domain.EsCircuitCodeDataTemplate;
import com.ehotting.edsta.circuitDesign.domain.EsCircuitType;
import com.ehotting.edsta.circuitDesign.domain.EsRuleScript;
import com.ehotting.edsta.circuitDesign.gen.arguments.helper.ArgumentScriptHelper;
import com.ehotting.edsta.circuitDesign.gen.arguments.script.*;
import com.ehotting.edsta.circuitDesign.gen.ScriptConstants;
import com.ehotting.edsta.circuitDesign.service.IEsRuleScriptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Service
public class ArgumentsScriptFactory {

    private static Logger logger = LoggerFactory.getLogger(ArgumentsScriptFactory.class);

    @Autowired
    private IEsRuleScriptService esRuleScriptService;
    @Autowired
    private ArgumentScriptHelper argumentScriptHelper;
    @Autowired
    private AssignmentArgumentsScript assignmentArgumentsScript;
    @Autowired
    private CustomArgumentsScript customArgumentsScript;
    @Autowired
    private ConditionArgumentsScript conditionArgumentsScript;

    private List<ArgumentsScriptAble> codeList = new ArrayList();

    @PostConstruct
    public void init(){
        codeList.add(assignmentArgumentsScript);
        codeList.add(customArgumentsScript);
        codeList.add(conditionArgumentsScript);
    }

    public String genMethod(EsCircuitType circuitType, RequestCodeExecute inputParam,List<EsCircuitCodeDataTemplate>  circuitCodeDataTemplateList){
        StringBuffer buf = new StringBuffer();
        for(EsCircuitCodeDataTemplate circuitCodeDataTemplate : circuitCodeDataTemplateList){
            List<EsRuleScript> esRuleScriptList = esRuleScriptService.findBySceneIdAndTypeAndState(
                    circuitCodeDataTemplate.getId(),
                    SceneTypeEnum.FILTER_PARAM,
                    StateTypeEnum.YES);
            for(EsRuleScript script : esRuleScriptList){
                genMethod(buf,  script,   inputParam, circuitCodeDataTemplateList);
            }
        }

        return buf.toString();
    }

    private void genMethod(StringBuffer buf, EsRuleScript script, RequestCodeExecute inputParam, List<EsCircuitCodeDataTemplate> outputParamList){
        for (ArgumentsScriptAble code : codeList) {
            boolean isTrue = code.isTrue(script.getType());
            //logger.info("code.getClass():{},isTrue:{},esRule.getType():{}", code.getClass(), isTrue, script.getType());
            if (isTrue) {
                buf.append(code.invoke(script,
                        inputParam.getArgumentsList(),
                        outputParamList,
                        genMethodName(script)));
                buf.append(ScriptConstants.LINE);
            }
        }
    }

    public String genCall(List<EsCircuitCodeDataTemplate>  circuitCodeDataTemplateList, List<String>  inputParamList) {
        StringBuffer buf = new StringBuffer();
        for(EsCircuitCodeDataTemplate circuitCodeDataTemplate : circuitCodeDataTemplateList){
            List<EsRuleScript> scriptList = esRuleScriptService.findBySceneIdAndTypeAndState(circuitCodeDataTemplate.getId(), SceneTypeEnum.FILTER_PARAM, StateTypeEnum.YES);
            for(EsRuleScript esRule: scriptList){
                genCall(buf, esRule,   inputParamList);
            }
        }

        return buf.toString();
    }

    private void genCall(StringBuffer buf,EsRuleScript esRuleScript,  List<String> inputParamList){
        buf.append(ScriptConstants.TAB);
        buf.append(argumentScriptHelper.genMethodNameAndArgument(genMethodName(esRuleScript),inputParamList));
        buf.append(";");
        buf.append(ScriptConstants.LINE);
    }

    private String genMethodName(EsRuleScript script){
        return "argument_"+script.getType().toString().toLowerCase() + "_"+script.getId();
    }

}